#include <iostream>
#include "../UdpClient.hpp"
#include "Thread.hpp"

void Usage(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

// 该进程任务负责接收信息
void Receiver(int sockfd)
{
    char recvbuf[1024];
    while (1)
    {
        struct sockaddr_in temp;
        socklen_t len = sizeof(temp);
        ssize_t nbytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf) - 1, 0, (struct sockaddr*)&temp, &len);
        if (nbytes > 0)
        {
            recvbuf[nbytes] = '\0';
            std::cerr << "Received: " << recvbuf << std::endl;
        }
        else
        {
            break;
        }
    }
}

// 该进程任务负责发送信息
void Sender(int sockfd, const sockaddr_in* server)
{
    while (1)
    {
        std::string message;
        std::cout << "Enter message to send: \n";
        std::getline(std::cin, message);

        socklen_t len = sizeof(*server);
        ssize_t nbytes = sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)server, len);
        if (nbytes > 0)
        {
            std::cout << "Send message successfully !" << std::endl;
        }
        else
        {
            break;
        }
    }
}

// ./udpclient serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    // UdpClient client(serverip, serverport);
    // client.start();
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in* server = new struct sockaddr_in;
    server->sin_family = AF_INET;
    server->sin_port = htons(serverport);
    server->sin_addr.s_addr = inet_addr(serverip.c_str());

    ThreadModule::Thread receiverThread("thread_receiver");
    ThreadModule::Thread senderThread("thread_sender");

    receiverThread.start(Receiver, sockfd);
    senderThread.start(Sender, sockfd, server);

    receiverThread.join();
    senderThread.join();

    return 0;
}